﻿using System;
using System.IO;
using System.Drawing;
using System.Collections;
using System.Text;
using ui = System.ComponentModel;
using Microsoft.BizTalk.Component.Interop;
using Microsoft.BizTalk.Message.Interop;
using Microsoft.BizTalk.Bam.EventObservation;
using System.Xml;
using Microsoft.BizTalk.Streaming;
using System.Collections.Generic;
using System.Linq;
using Microsoft.BizTalk.SSOClient.Interop;

namespace BizTalk.ESB.Extensions.PipelineComponents
{
    [ComponentCategory(CategoryTypes.CATID_PipelineComponent),
     ComponentCategory(CategoryTypes.CATID_Any)]
    public class SSOGetTicket : IBaseComponent, IComponent, IComponentUI, IPersistPropertyBag
    {
        #region PrivateFields

        private const string DescriptionProperty = "Custom Pipeline Component to obtain an SSO ticket";
        private const string NameProperty = "BizTalk.ESB.Extensions.PipelineComponent.SSOGetTicket";
        private const string VersionProperty = "1.0";
        private const string EnabledProperty = "Enabled";

        private bool _Enabled = true;
        
        #endregion

        #region PublicProperties

        [ui.TypeConverter(typeof(ContextPropertyTypeConverter))]
        public bool Enabled { get { return _Enabled; } set { _Enabled = value; } }
      
        #endregion

        #region IBaseComponent

        public string Description
        {
            get
            {
                return DescriptionProperty;
            }
        }

        public string Name
        {
            get
            {
                return NameProperty;
            }
        }

        public string Version
        {
            get
            {
                return VersionProperty;
            }
        }

        #endregion

        #region IComponent

        public IBaseMessage Execute(IPipelineContext pipeLineContext, IBaseMessage baseMessage)
        {
            if (Enabled)
            {
                ISSOTicket ticket = new ISSOTicket();
                string ticketVal = ticket.IssueTicket(SSOFlag.SSO_FLAG_NONE);
                BTS.SSOTicket ticketprop = new BTS.SSOTicket();
                
                baseMessage.Context.Write(ticketprop.Name.Name, ticketprop.Name.Namespace, ticketVal);
                
            }

            return baseMessage;
        }

        #endregion

        #region IComponentUI

        public IntPtr Icon
        {
            get
            {
                return new IntPtr();
            }
            //return ((Bitmap)resManager.GetObject("FixMsgBitmap")).GetHicon();
        }

        public IEnumerator Validate(object projectSystem)
        {
            IEnumerator enumerator = null;

            return enumerator;
        }

        #endregion

        #region IPersistPropertyBag

        public void GetClassID(out Guid classId)
        {
            classId = new System.Guid("A230630D-FA2E-44C9-A3A5-2841C208AF46");
        }

        public void InitNew()
        {

        }

        public void Load(Microsoft.BizTalk.Component.Interop.IPropertyBag propertyBag, int errorLog)
        {
            object enabled = ReadPropertyBag(propertyBag, EnabledProperty);
            if (enabled != null)
                Enabled = (bool)enabled;
        }

        public void Save(Microsoft.BizTalk.Component.Interop.IPropertyBag propertyBag, bool clearDirty, bool saveAllProperties)
        {
            //Enabled
            var val = (object)this.Enabled;
            WritePropertyBag(propertyBag, EnabledProperty, val);
        }

        #endregion

        #region CustomMethods

        /// <summary>
        /// Reads property value from property bag.
        /// </summary>
        /// <param name="pb">Property bag.</param>
        /// <param name="propName">Name of property.</param>
        /// <returns>Value of the property.</returns>
        private static object ReadPropertyBag(Microsoft.BizTalk.Component.Interop.IPropertyBag pb, string propName)
        {
            object val = null;
            try
            {
                pb.Read(propName, out val, 0);
            }

            catch (ArgumentException)
            {
                return val;
            }
            catch (Exception ex)
            {
                throw new ApplicationException(ex.Message);
            }
            return val;
        }

        /// <summary>
        /// Writes property values into a property bag.
        /// </summary>
        /// <param name="pb">Property bag.</param>
        /// <param name="propName">Name of property.</param>
        /// <param name="val">Value of property.</param>
        private static void WritePropertyBag(Microsoft.BizTalk.Component.Interop.IPropertyBag pb, string propName, object val)
        {
            try
            {
                pb.Write(propName, ref val);
            }
            catch (Exception ex)
            {
                throw new ApplicationException(ex.Message);
            }
        }

        private static ContextProperty ConvertToContextProperty(string contextPropertyString)
        {
            if (!string.IsNullOrEmpty(contextPropertyString))
            {
                //Parse the format "PropertyName, PropertyNamespace"
                int comma = contextPropertyString.IndexOf(',');
                if (comma != -1)
                {
                    string[] contextPropertyStrings = contextPropertyString.Split(',');

                    if (contextPropertyStrings.Length == 2)
                    {
                        var contextProperty = new ContextProperty();
                        contextProperty.PropertyName = contextPropertyStrings[0];
                        contextProperty.PropertyNamespace = contextPropertyStrings[1];

                        return contextProperty;
                    }
                }
            }

            return new ContextProperty()
            {
                PropertyName = string.Empty,
                PropertyNamespace = string.Empty
            };
        }

        private static string ConvertToString(ContextProperty contextProperty)
        {
            //Simply build the string
            if (string.IsNullOrEmpty(contextProperty.PropertyName) && string.IsNullOrEmpty(contextProperty.PropertyNamespace))
                return string.Empty;

            return contextProperty.PropertyName + "," + contextProperty.PropertyNamespace;
        }

        private static string ExtractMessageInfo(ContextProperty contextProperty, IBaseMessage baseMessage)
        {
            var contextValue = (string)baseMessage.Context.Read(contextProperty.PropertyName,
                                                                contextProperty.PropertyNamespace);

            if (string.IsNullOrEmpty(contextValue))
                contextValue = string.Empty;


            return contextValue;
        }

        #endregion
    }
}
